
import java.io.IOException;
import java.util.*;
import java.text.*;

public class Parser {
	 //the add format is very weird for the first one
	
	// Now we assume details entered by the user after the command will be enough
	//for us to find a single matched task or event.
	
	//strictly must pass the input as following for delete,edit,search,mark
	
	//add command may need change!as do not know what is passing from CLI
	
	/********************************************
	 * example input:
	 * add: [add][name][from][starttime][to][endtime][priority]
	 *      [add][name][due][starttime][priority]
	 *
	 * delete: [delete]["name"]
	 *         [delete][from]["start time(date)"]
	 *         [delete][to]["end time(date)"]
	 *
	 * edit: [edit][name][change]["old name"][to]["new"]
	 *       [edit][name][change]["old name"][to]["new"][from]["start time"]
	 *       [edit][name][change]["old name"][to]["new"][on]["end time"]
	 *       
	 *       [edit][priority][change]["old"][to]["new"][for]["task\event name"]\\if only know name
	 *       [edit][priority][change]["old"][to]["new"][from]["start time"]
	 *       [edit][priority][change]["old"][to]["new"][to]["end time"]
	 *       
	 *       [edit][start time][change]["old"][to]["new"][from][start time]
	 *       [edit][end time][change]["old"][to]["new"][to][end time]
	 * search: 
	 *       [search][name]["name"]
	 *       [search][time][from]["start time]
	 *       [search][time][to]["end time"]
	 *       
	 * mark:
	 *      [mark]["name"]
	 *      [mark][from]["start time"]
	 *      [mark][to]["end time"]
	 *
	 * " " indicate change variables others indicate fixed variables.
	 * 
	 */
    logic logicClass=new logic();
	static DateFormat formatter = new SimpleDateFormat("mm-HH-dd-MM-yyyy");
	private static final String MESSAGE_EMPTY_COMMAND_TYPE = "command type string cannot be empty";
	private static final String MESSAGE_INVALID_FORMAT = "Unrecognized command type";

	

	
	//Possible input from user
	enum COMMAND_TYPE {ADD, DELETE, SEARCH, EDIT, MARK, INVALID};
			
	public  String processInput(String userInput) throws IOException, ParseException {		
		
		String command_type_string = getFirstWord(userInput);
		COMMAND_TYPE command_type = determineCommandType(command_type_string);
		String content = removeFirstWord(userInput);
		String delimiter = " ";
		String[] temp = content.split(delimiter);
		
	switch(command_type){
		case ADD: {	
			if(temp.length==4){
			      String name = temp[0];
			      Date startTime = (Date)formatter.parse(temp[1]);
			      Date endTime = (Date)formatter.parse(temp[2]);
			      int priority = Integer.parseInt(temp[3]);
			    return logicClass.add(name, startTime, endTime, false,priority);
			        
	            
	           }
			if(temp.length==3){
				 String name = temp[0];
			     Date startTime = (Date)formatter.parse(temp[1]);
			     int priority = Integer.parseInt(temp[2]);
				return logicClass.add(name, startTime,priority);
			   
			   }
			 break;
		  }
		
		case DELETE: {
			if(containsOnlyChars(temp[0])){
				if(logicClass.delete(temp[0]))
				return("delete successfully");
				else
					return("delete not successfullu");
				
			   }
			if(temp[0].equalsIgnoreCase("from")){
				Date startTime = (Date)formatter.parse(temp[1]);
				if(logicClass.delete(DataStruc.DATE_TYPE.start, startTime))
				return ("delete successfully");
				else
					return ("not successfully");
				
				}
			if(temp[0].equalsIgnoreCase("to")){
			    Date endTime = (Date)formatter.parse(temp[1]);
			   if( logicClass.delete(DataStruc.DATE_TYPE.end, endTime))
				   return("delete successfully");
			   else
				   return("not successfully");
			  }
			break;
		}
	    
		case SEARCH: {
			if(temp[0].equalsIgnoreCase("name")){
			   Vector<Task> task=new Vector<Task> ();
				task=logicClass.search(temp[1]);
				if(task==null){
					return("no result found");
				}
				else
					return("search result");
			}
			if(temp[0].equalsIgnoreCase("time")){
				if(temp[1].equalsIgnoreCase("from")){
					Date startTime = (Date)formatter.parse(temp[2]);
					Task task;
					task=logicClass.search(DataStruc.DATE_TYPE.start, startTime);
					if(task==null)
						return("no result found");
					else
					    return("search result");
				}
				if(temp[1].equalsIgnoreCase("to")){
					Date endTime = (Date)formatter.parse(temp[2]);
					Task task;
					task=logicClass.search(DataStruc.DATE_TYPE.end, endTime);
					if(task==null)
						return("no result found");
					else
					   return("search result");
					}
				
		           }
		            break;
		          }
		 
		
		case EDIT:{ 
			if(temp[0].equalsIgnoreCase("name")){
				DataStruc.DATE_TYPE type;
				String name = temp[2];	
				String newname=temp[4];
				if(temp[5].equalsIgnoreCase("from")){
					type=DataStruc.DATE_TYPE.start;
					Date time = (Date)formatter.parse(temp[6]);
				}
				if(temp[5].equalsIgnoreCase("to")){
				     type=DataStruc.DATE_TYPE.end;
				     Date time = (Date)formatter.parse(temp[6]);
				}
		
				type=null;
				Date time=null;//problems!!!!
			if(logicClass.editName(name, type, time, newname))
				return("edit successfully"); 
				else
					return("edit not successfully");
				}
		   break;
		}
	     
	     //mark:
		 //     [mark]["name"]
		 //     [mark][from]["start time"]
		 //     [mark][to]["end time"]
		 
		case MARK: {
			if(temp[0].equalsIgnoreCase("from")){
				Date time = (Date)formatter.parse(temp[1]);
				if(logicClass.mark(null, DataStruc.DATE_TYPE.start, time))
					return("mark successfully");
				else
					return("mark not successfully");
			   }
			  if(temp[0].equalsIgnoreCase("to")){
				Date time = (Date)formatter.parse(temp[1]);
				if(logicClass.mark(null, DataStruc.DATE_TYPE.end, time))
					return("mark successfully");
				else
					return("mark not successfully");
			   }
			  if(temp.length==1){
				if(logicClass.mark(temp[0], null, null))
					return("mark successfully");
				else
					return("mark not successfully");
			   }
			break;
			}
		default:
			throw new Error(MESSAGE_INVALID_FORMAT);
		}
	return("");
	}
	

	private  COMMAND_TYPE determineCommandType(String commandTypeString) {
		if(commandTypeString==null)
			throw new Error(MESSAGE_EMPTY_COMMAND_TYPE);
		
		if(commandTypeString.equalsIgnoreCase("add")) 
			return COMMAND_TYPE.ADD;
		else if (commandTypeString.equalsIgnoreCase("delete")) 
			return COMMAND_TYPE.DELETE;
		else if (commandTypeString.equalsIgnoreCase("search")) 
			return COMMAND_TYPE.SEARCH;
		else if (commandTypeString.equalsIgnoreCase("edit")) 
			return COMMAND_TYPE.EDIT;
		else if (commandTypeString.equalsIgnoreCase("mark")) 
			return COMMAND_TYPE.MARK;
		else 
			return COMMAND_TYPE.INVALID;
	}
	
	
	private String getFirstWord(String userCommand) {
		String commandTypeString = userCommand.trim().split("\\s+")[0];
		return commandTypeString;
	}
	
	
	private  String removeFirstWord(String userCommand) {
		return userCommand.replace(getFirstWord(userCommand), "").trim();
	}
	 private  boolean containsOnlyChars(String text) {
         if (text == null || text.length() == 0)
            return false;
         for (int i = 0; i < text.length(); i++) {
                if (Character.isDigit(text.charAt(i)))
                return false;
        }
        return true;
    }
	 
	 public String displayToday() {
		 return logicClass.displayToday();
	 }
}

